"""
检测服务模块
"""
import random 
import time
import threading
from datetime import datetime
from system.logger import Logger
from services.system_service import system_service

from arm_module import Control_Arm as arm
from tpu_module import Control_TPU as tpu
from cap import VideoCapture
from voice_module import Control_Voice

import os
import sys

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
from system.detection_area import detect_edges, is_card_fully_detected
from system.grab_part import perform_grab

class DetectionService:
    """检测服务类"""
    
    def __init__(self, socketio=None):
        self.socketio = socketio
        self.logger = Logger(root_dir=".", verbose_info=True, verbose_error=True, verbose_detection=True)
        self.detection_thread = None
        # TODO: 支持动态修改
        self.defect_target_config = {
            'crazing': [-150, -190],
            'inclusion': [-150, -150],
            'patches': [-150, -130],
            'pitted_surface': [150, -190],
            'rolled_in_scale': [150, -150],
            'scratches': [150, -130]
        }
    
    def start_detection_loop(self):
        """启动检测循环"""
        print("启动检测循环")
        if self.detection_thread and self.detection_thread.is_alive():
            return False
        
        self.detection_thread = threading.Thread(target=self._detection_loop)
        self.detection_thread.daemon = True
        self.detection_thread.start()
        return True
    
    def stop_detection_loop(self):
        """停止检测循环"""
        # 检测循环会在系统状态改变时自动停止
        pass

    def _select_best_box(self, results):
        """从检测结果列表中选择置信度最高的框"""
        if not isinstance(results, list) or len(results) == 0:
            return None
        
        # 根据置信度排序（降序），选择第一个
        best_box = max(results, key=lambda x: x[4])  # x[4] 是置信度
        return best_box

    # 修改抓取位置接口
    def update_defect_target_config(self, defect_type, position):
        """更新指定缺陷类型的目标抓取位置"""
        if not isinstance(position, list) or len(position) != 2:
            raise ValueError("Position must be a list of two integers: [x, y]")
        self.defect_target_config[defect_type] = position


    def run_real_detection(self, model_name="neu2_test", conf=0.4, iou=0.45, width=640, height=640):
        """运行一次真实检测流程"""
        try:
            arm.reset_position()
            cap = VideoCapture()
            img = cap.read()
            
            # 检测边缘
            edges = detect_edges(img)

            # 检查卡片边缘是否完全进入视野
            if is_card_fully_detected(edges):
                print("卡片已完全进入视野，开始缺陷检测")
                
                result = tpu.predict(img, mode=False, model_name=model_name,
                                     conf=conf, iou=iou, w=width, h=height)
                
                # cap.release()

                print(result)

                box = self._select_best_box(result)

                if box is not None:
                    x1, y1, x2, y2, confidence, defect_type = box

                    # —— 新增：发送串口命令 —— 
                    classes = ["crazing", "inclusion", "pitted_surface", "patches", "rolled-in-scale", "scratches"]
                    idx = classes.index(defect_type)
                    Control_Voice.send(idx + 1)
                    print(f"DEBUG: detect {defect_type}, send AA 55 {idx+1:02X} 55 AA")
                    # —— 新增结束 ——

                    # 格式转换以适配系统统计结构
                    detection_result = {
                       'status': 'defective',
                       'type': defect_type,
                       'confidence': confidence,
                       'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                       'frame_id': system_service.status['total_processed'] + 1
                   }
                    
                    grab_point = [0, -170]
                    target_point = self.defect_target_config.get(defect_type)
                    perform_grab(grab_point, target_point)

                    cap.release()

                else:
                    detection_result = {
                        'status': 'normal',
                        'type': 'none',
                        'confidence': 0.0,
                        'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                        'frame_id': system_service.status['total_processed'] + 1
                    }

                # 更新统计数据
                system_service.update_detection_stats(
                    is_defective=(detection_result['status'] == 'defective'),
                    defect_type=detection_result.get('type')
                )

                # 记录检测时间
                system_service.status['last_detection_time'] = detection_result['timestamp']

                # 日志记录
                self._log_detection_result(detection_result)

                # 推送前端
                if self.socketio:
                    self._emit_detection_result(detection_result)

                return detection_result
            else:
                print("卡片未完全进入视野，空检测")
                return {"status": "normal", "error": "Card not fully detected"}

        except Exception as e:
            if self.logger:
                self.logger.error(f"Real detection failed: {str(e)}")
            return {"status": "error", "error": str(e)}
    
    def _detection_loop(self):
        """检测循环主逻辑"""
        while system_service.is_running():
            time.sleep(1)  # 模拟检测间隔
            
            if not system_service.is_running():
                break
            
            # 调用真实检测
            result = self.run_real_detection(
              model_name="neu2_test",
              conf=0.2,
              iou=0.25,
              width=640,
              height=640
            )
            
            if result.get('status') == 'error':
                self.logger.error(f"Detection error: {result.get('error')}")
                continue
            
            # 发送实时数据到前端
            if self.socketio:
                self._emit_detection_result(result)
    
    
    def _log_detection_result(self, result):
        """记录检测结果日志"""
        self.logger.detection(
            status=result['status'],
            defect_type=result['type'],
            confidence=result['confidence'],
            frame_id=result['frame_id']
        )
    
    def _emit_detection_result(self, result):
        """向前端发送检测结果"""
        self.socketio.emit('detection_result', result)
        
        # 发送统计数据更新
        status = system_service.get_status()
        self.socketio.emit('statistics_update', {
            'total_processed': status['total_processed'],
            'total_normal': status['total_normal'],
            'total_defective': status['total_defective'],
            'defect_counts': status['defect_counts']
        })

# 全局检测服务实例
detection_service = None 